#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         Wizard.py
#
# Copyright:    Copyright (c) 2005, Faulkner Technologies
#
# Author:       Brian Oliver
#
# Description:  SimpleWizards provide a basic mechanism for 
#               simplifying the declaration of the properties of 
#               the steps of a wizard 
#
# See Also:     Wizard, WizardStepDefinition, PropertyDefinition
#####################################################################

#####################################################################
## KnowledgeEngine Library Imports
from Common import *
from Wizard import Wizard

#####################################################################
## Zope Library Imports
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
from AccessControl.Role import RoleManager
 
#####################################################################
## Python Library Imports
# (none)

#####################################################################
## SimpleWizard Interface Definition
class SimpleWizard(Wizard):
    """
        A simple class that specified how to manage a collection of 
        paged / step-wise properties to edit/display
    """

    #---------------------------------------------------------------#

    #define security
    security = ClassSecurityInfo()
    security.declareObjectPublic()
    security.setDefaultAccess("allow")
        
    #by default there are no wizardStepDefinitions
    wizardStepDefinitions = []

    #---------------------------------------------------------------#

    def __init__(self, wizardStepDefinitions = []):
        """
            SimpleWizard constructor.
            
            PARAMETERS:
            wizardStepDefinitions: An optional list of wizardStepDefinitions.
                                   If not provided, it is assumed that the
                                   this class is subclassed and the method
                                   'getWizardStepDefinitions' has been
                                   overridden.
        """
        
        self.wizardStepDefinitions = wizardStepDefinitions
        
    #---------------------------------------------------------------#
        
    def getWizardStepDefinitions(self, context=None):
        """
            ABSTRACT: This method is used by this class to
            determine the actual wizard step definitions
            for the wizard.  If this class is sub-classed,
            this method should be overridden.
            
            PARAMS:
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions
            
            RETURN: [WizardStepDefinition]
        """
        
        #return the constructor provided wizardStepDefinitions
        return self.wizardStepDefinitions
        
    #---------------------------------------------------------------#
        
    def getTotalWizardSteps(self, wizardState, context=None):
        """
            FINAL: Returns the number of wizard steps 
            given the specified wizardState.
            
            PARAMS:
            wizardState - the current properties of the wizard in action
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions
            
            NOTE: Step 1 is the first step!

            RETURN: Integer
        """
        
        #return the number of defined wizard steps
        return len(self.getWizardStepDefinitions(context))

    #---------------------------------------------------------------#

    def getWizardStepTitle(self, wizardState, context=None):
        """
            FINAL: Return the title of the specified wizard step
            using the provided wizard state.
            
            PARAMS:
            wizardState - the current properties of the wizard in action
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions
            
            By default returns 'Step # of #'.  Override this
            method if you'd like something else.

            RETURN: String
        """            
        
        #determine the wizard steps
        wizardStepDefinitions = self.getWizardStepDefinitions(context)
        totalWizardSteps = self.getTotalWizardSteps(wizardState, context)
        
        if totalWizardSteps >= 1:
            #grab the current and total steps... we're going to use them a few times         
            currentStep = self.getCurrentWizardStep(wizardState)
            
            if totalWizardSteps == 1: 
                return "%s" % (wizardStepDefinitions[currentStep-1].getTitle())
            else:                
                return "Step %d of %d : %s" % (currentStep, totalWizardSteps, wizardStepDefinitions[currentStep-1].getTitle())
            
        else:
            return "Wizard"
        
    #---------------------------------------------------------------#
        
    def getWizardStepDescription(self, wizardState, context=None):
        """
            FINAL: Returns the description of the specified wizard step
            using the provided wizard state.
            
            PARAMS:
            wizardState - the current properties of the wizard in action
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions

            RETURN: String
        """
        
        if self.getTotalWizardSteps(wizardState, context) >= 1:
            return self.getWizardStepDefinitions(context)[self.getCurrentWizardStep(wizardState) -1].getDescription()
        else:
            return ""
        
    #---------------------------------------------------------------#
        
    def getPropertyDefinitionsForWizard(self, wizardState, context=None):
        """
            Returns a list of all PropertyDefinitions for 
            the wizard using the provided wizardState (if necessary)
            
            PARAMS:
            wizardState - the current properties of the wizard in action
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions
            
            RETURN: [PropertyDefinition]
        """            
        
        #a set of all properties (we want to ensure a set as properties may exist on multiple wizard steps!)
        allProperties = {}

        #add all of the wizardstep definition properties to the result!        
        for wizardStepDefinition in self.getWizardStepDefinitions(context):
            for propertyDefinition in wizardStepDefinition.getPropertyDefinitions():            
                allProperties[propertyDefinition.getIdentity()] = propertyDefinition
        
        return allProperties.values()
        
    #---------------------------------------------------------------#
        
    def getPropertyDefinitionsForWizardStep(self, wizardState, context=None):
        """
            Returns a list of PropertyDefinitions for the specified
            wizard step using the provided wizardState (if necessary)
            
            PARAMS:
            wizardState - the current properties of the wizard in action
            context - usually a GenericObject instance that may 
                      be used to dynamically determine wizard
                      step definitions
            
            RETURN: [PropertyDefinition]
        """            
        
        return self.getWizardStepDefinitions(context)[self.getCurrentWizardStep(wizardState) -1].getPropertyDefinitions()
        
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation
InitializeClass(SimpleWizard)
